/*file chiron src/transition.js */
/*preamble

    Copyright (c) 2002-2008 Kris Kowal <http://cixar.com/~kris.kowal>
    MIT License
    
    The license terms are stated in full in <license.rst> and at the end
    of all source files.

*/


/**
    provides transition functions and mechanisms for creating
    parameterized transition functions.  A transition function
    transforms a progress value (a value launching at 0 and landing
    on 1) to another progress value following a non-linear
    curve.  Since transition functions both accept and return
    progress values, they are "self-decorating", meaning you
    can compose or pipeline them to construct new curves.

    These first functions create transition functions:
*/

/*** reversed
    reverses the curve of a transition.  For example, 
    a reversed bounce transition will bounce on the
    landing side instead of bouncing off of the launch side.
*/
exports.reversed = function (transition) {
    return function (progress) {
        return 1 - transition(1 - progress);
    };
};

/*** mirror
    mirrors a transition.  For example, a mirrored bounce
    transition will bounce both off the launch side and
    on the landing side.
*/
exports.mirror = function (transition) {
    return function (progress) {
        return (
            progress <= 0.5 ?
            transition(2 * progress) / 2 :
            (2 - transition(2 * (1 - progress))) / 2
        );
    };
};

/*** power
    returns a power transition given an exponent.
    Power creates transitions like linear, quadratic,
    cubic, quintic, quartic for exponents starting with
    one respectively.  As the exponent of a power
    transition increases, the progress lingers
    longer at the launch side and arcs more severely
    at the landing side.  A reversed power
    transition gives the appearance of initial haste
    and a gentle touchdown.
*/
exports.power = function (exponent) {
    return function (progress){
        return Math.pow(progress, exponent);
    };
};

/*** damped
    returns an underdamped transition.  An underdamped
    transition dips below the launch point before
    shooting up.
*/
exports.damped = function (ratio) {
    return function (progress) {
        return Math.pow(progress, 2) * ((ratio + 1) * progress - ratio);
    };
};

/*** overDamped
    returns an overdamped transition.  An overdamped
    transition oscillates several times with increasing
    amplitude before launching.
*/
exports.overDamped = function (elasticity) {
    return function (progress) {
        return (
            Math.pow(2, 10 * --progress) *
            Math.cos(
                20 * progress * Math.PI * (elasticity || 1) / 3
            )
        );
    };
};

/**
    -------------------------

    The following are pre-created transition functions.
*/

/*** quadratic
    a second order power transition.
*/
exports.quadratic = power(2);

/*** cubic
    a third order power transition.
*/
exports.cubic = power(3);

/*** quartic
    a fourth order power transition.
*/
exports.quartic = power(4);

/*** quintic
    a fifth order power transition.
*/
exports.quintic = power(5);

/*** exponential
    a base two exponential transition.
*/
exports.exponential = function (progress) {
    return Math.pow(2, 8 * (progress - 1));
};

/*** circle
    a transition that traces the arc of a circle
    that launches slowly and lands quickly.
*/
exports.circle = function (progress) {
    return 1 - Math.sin(Math.acos(progress));
};

/*** sin
    a transition that models the first half of a
    sinuseudal wave launching slowly from 
    the bottom of its amplitude.  ``mirror``
    a ``sin`` transition to construct a sinuseudal
    transition that eases in and out.
*/
exports.sin = function (progress) {
    return 1 - Math.sin((1 - progress) * Math.PI / 2);
}

/*** bounce
    a transition that bounces from its launch
    site until it reaches the landing.
*/
exports.bounce = function (progress) {
    var value;
    for (var a = 0, b = 1; 1; a += b, b /= 2){
        if (progress >= (7 - 4 * a) / 11){
            value = - Math.pow((11 - 6 * a - 11 * progress) / 4, 2) + b * b;
            break;
        }
    }
    return value;
};

/**
    ----------------------------------------------------------
*/

exports.journey = function (transition) {
    return function (progress) {
        return progress <= .5 ?
            transition(progress * 2) : 
            transition(1 - (progress - .5) * 2)
        ;
    };
};

/**
    References
    ==========

    http://svn.mootools.net/trunk/Effects/Fx.Transitions.js
      This module is based on Mootools effect transitions albeit
      with certain liberties of design and nomenclature.
      MIT License.

    http://www.robertpenner.com/easing/
      In turn, Mootools is based on Robert Penner's easing functions
      with certain liberties of design and performance.
      BSD License.

*/


/*license

    Legal
    =======
    
    Chiron is a component of the Tale web-game project.
    
    See <credit.txt> for a complete list of
    contributions and their licenses.  All contributions are provided
    under permissive, non-viral licenses including MIT, BSD, Creative Commons
    Attribution 2.5, Public Domain, or Unrestricted.
    
    
    License
    =======
    
    Copyright (c) 2002-2008 Kris Kowal <http://cixar.com/~kris.kowal>
    MIT License
    
    
    MIT License
    -----------
    
    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following
    conditions:
    
    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

*/

